package jnpf.database.enums;

import com.baomidou.mybatisplus.annotation.DbType;
import jnpf.base.DbTableModel;
import jnpf.database.model.DbTableFieldModel;
import jnpf.database.model.dto.DbListVO;
import jnpf.database.source.DbBase;
import jnpf.util.JdbcUtil;
import lombok.Cleanup;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 *
 * 模型枚举
 * @author JNPF开发平台组
 * @version V3.1.0
 * @copyright 引迈信息技术有限公司
 * @date 2021年6月30日
 */
public enum DbModelEnum {

    /**
     * 表模型
     */
    TABLE_MODEL{
        @Override
        public String getModelSql(DbBase dbBase) {
            return dbBase.getListSql();
        }

        @Override
        public DbListVO getModel(ResultSet result, DbBase dbBase) throws SQLException {
            DbListVO dbListVO = new DbListVO();
            dbListVO.setDbTableModel( dbBase.getTableModel(result));
            return dbListVO;
        }

        @Override
        public DbListVO getModelList(Connection conn, String sql, DbBase dbBase) {
            try {
                return getResultList(conn, dbBase, DbModelEnum.TABLE_MODEL, sql);
            } catch (SQLException e) {
                e.getMessage();
            }
            return null;
        }
    },
    /**
     * 字段模型
     */
    FIELD_MODEL {
        @Override
        public String getModelSql(DbBase dbBase) {
            return dbBase.getFieldSql();
        }

        @Override
        public DbListVO getModel(ResultSet result, DbBase dbBase) throws SQLException {
            DbListVO dbListVO = new DbListVO();
            dbListVO.setDbTableFieldModel(dbBase.getFieldModel(result, null));
            return dbListVO;
        }

        @Override
        public DbListVO getModelList(Connection conn, String sql, DbBase dbBase) {
            List<DbTableFieldModel> list = new ArrayList<>();
            try {
                //Oracle特定一些方法
                if (dbBase.getDbEncode().equals(DbType.ORACLE.name().toLowerCase())) {
                    @Cleanup ResultSet result = JdbcUtil.query(conn, sql);
                    List<Map<String, Object>> mapList = JdbcUtil.convertList2(result);
                    for (Map<String, Object> map : mapList) {
                        DbTableFieldModel model = dbBase.getFieldModel(result, map);
                        if (!list.contains(model)) {
                            list.add(model);
                        }
                    }
                    Collections.reverse(list);
                } else {
                    return getResultList(conn, dbBase, DbModelEnum.FIELD_MODEL, sql);
                }
            } catch (SQLException e) {
                e.getMessage();
            }
            DbListVO dbListVO = new DbListVO();
            dbListVO.setDbTableFieldList(list);
            return dbListVO;
        }
    }
    ;


    /**
     * 从result获取list
     * @param conn 数据源
     * @param dbBase 数据库类型
     * @param dbModelEnum 模型枚举
     * @param sql SQL语句
     * @return 数据List容器
     * @throws SQLException 异常
     */
    public static  DbListVO getResultList(Connection conn, DbBase dbBase, DbModelEnum dbModelEnum,String sql) throws SQLException {
        DbListVO dbListVO = new DbListVO();
        @Cleanup ResultSet result = JdbcUtil.query(conn,sql);
        List<DbTableModel> list1 = new ArrayList<>();
        List<DbTableFieldModel> list2 = new ArrayList<>();
        while (result.next()) {
            DbListVO models = dbModelEnum.getModel(result,dbBase);
            if(models.getDbTableModel()!=null){
                DbTableModel model = models.getDbTableModel();
                if (!list1.contains(model)) {
                    list1.add(model);
                }
            }else {
                DbTableFieldModel model = models.getDbTableFieldModel();
                if (!list2.contains(model)) {
                    list2.add(model);
                }
            }
        }
        dbListVO.setDbTableList(list1);
        dbListVO.setDbTableFieldList(list2);
        return dbListVO;
    }



    DbModelEnum(){
    }

    public abstract String getModelSql(DbBase dbBase);

    public abstract DbListVO getModel(ResultSet result, DbBase dbBase) throws SQLException;

    public abstract DbListVO getModelList(Connection conn, String sql, DbBase dbBase);

}
